package gestion.comunicacion;

import entidades.Jugador;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import ventanasYDialogos.VElegirColor;
import ventanasYDialogos.VPrincipal;

public class Cliente extends Thread {

    private Socket socketCliente;
    private PrintWriter salida;
    private BufferedReader entrada;
    private boolean corre = true;
    private String ipServidor;
    private VElegirColor vec;
    private String delimitador = "&-&-&";
    private VPrincipal vp;
    private int id;
    private int[] tarjetas = new int[50];
  

    public Cliente(String ipServidor, VElegirColor vec) {
        this.ipServidor = ipServidor;
        this.vec = vec;
    }

    public void run() {
        if (vec != null) {
            try {
                socketCliente = new Socket(ipServidor, 4444);
                salida = new PrintWriter(socketCliente.getOutputStream(), true);
                entrada = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
                System.out.println("Cliente en linea...");
                String lineaEntrada;
                conocerNombrePartida();
                conocerColoresOcupados();
                while (corre) {
                    if ((lineaEntrada = entrada.readLine()) != null) {
                        if (lineaEntrada.compareTo("abondonoJugador") == 0) {
                            vp.abortar();
                        } else if (lineaEntrada.compareTo("finMazoTarjeta") == 0) {
                            vp.mezclarMazo();
                        } else if (lineaEntrada.compareTo("finTurno") == 0) {
                            vp.cambiarTurno();
                        } else if (lineaEntrada.compareTo("solicitarTarjeta") == 0) {
                            vp.sacarTarjeta();
                        } else if (lineaEntrada.compareTo("finRonda") == 0) {
                            vp.cambiarRonda();
                        } else {
                            ArrayList<String> contenidoLineaEntrada = analizarCadena(lineaEntrada);
                            if (contenidoLineaEntrada.get(0).compareTo("iniciarPartida") == 0) {
                                vec.iniciarPartida(construirArrayJugadores(contenidoLineaEntrada), construirArrayPaises(contenidoLineaEntrada), Integer.parseInt(contenidoLineaEntrada.get(contenidoLineaEntrada.size() - 2)), Integer.parseInt(contenidoLineaEntrada.get(contenidoLineaEntrada.size() - 1)), this.tarjetas);
                            } else if (contenidoLineaEntrada.get(0).compareTo("avisarNombrePartida") == 0) {
                                avisarClienteNombrePartida(contenidoLineaEntrada.get(1),contenidoLineaEntrada.get(3),contenidoLineaEntrada.get(4));
                                this.id = Integer.parseInt(contenidoLineaEntrada.get(2));
                            } else if (contenidoLineaEntrada.get(0).compareTo("color") == 0) {
                                avisarClienteSeleccionColor(contenidoLineaEntrada);
                            } else if (contenidoLineaEntrada.get(0).compareTo("avisarColores") == 0) {
                                avisarClienteColoresOcupados(contenidoLineaEntrada);
                            } else if (contenidoLineaEntrada.get(0).compareTo("mensaje") == 0) {
                                vp.avisarNuevoMensaje(Integer.parseInt(contenidoLineaEntrada.get(1)), contenidoLineaEntrada.get(2));
                            } else if (contenidoLineaEntrada.get(0).compareTo("nuevaTropaPais") == 0) {
                                int idP = Integer.parseInt(contenidoLineaEntrada.get(1));
                                vp.agregarTropaPais(idP);
                            } else if (contenidoLineaEntrada.get(0).compareTo("avisarAtaque") == 0) {
                                vp.actualizarAtaque(contenidoLineaEntrada);
                            } else if (contenidoLineaEntrada.get(0).compareTo("avisarReagrupacion") == 0) {
                                vp.actualizarReagrupacion(Integer.parseInt(contenidoLineaEntrada.get(1)), Integer.parseInt(contenidoLineaEntrada.get(2)));
                            } else if (contenidoLineaEntrada.get(0).compareTo("avisarFinPartida") == 0) {
                                vp.avisarFinPartida(Integer.parseInt(contenidoLineaEntrada.get(1)));
                            } else if (contenidoLineaEntrada.get(0).compareTo("usoTarjeta") == 0) {
                                vp.avisarUsoTarjeta(Integer.parseInt(contenidoLineaEntrada.get(1)));
                            } else if (contenidoLineaEntrada.get(0).compareTo("canjeTarjeta") == 0) {
                                vp.avisarCanjeTarjeta(Integer.parseInt(contenidoLineaEntrada.get(1)), Integer.parseInt(contenidoLineaEntrada.get(2)), Integer.parseInt(contenidoLineaEntrada.get(3)));
                            }

                        }

                    }
                }
            } catch (UnknownHostException ex) {
                System.out.println("1");
                Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                System.out.println("2");
                vec.avisarError();
            }
        }
    }

    public void avisarSeleccionColor(String color, String usuario) {
        salida.println("color" + delimitador + color + delimitador + usuario);
    }

    private ArrayList<String> analizarCadena(String test) {

        ArrayList<String> tokens = new ArrayList<String>();

        Scanner tokenize = new Scanner(test);
        tokenize.useDelimiter(delimitador);
        while (tokenize.hasNext()) {
            tokens.add(tokenize.next());
        }
        return tokens;
    }

    private void avisarClienteSeleccionColor(ArrayList<String> contenidoLineaEntrada) {
        vec.seleccionColor(contenidoLineaEntrada);
    }

    private void conocerColoresOcupados() {
        salida.println("conocerColores");
    }

    //Se ejecuta al inicio
    private void avisarClienteColoresOcupados(ArrayList<String> contenidoLineaEntrada) {
        vec.seleccionColoresOcupados(contenidoLineaEntrada);
    }

    private void conocerNombrePartida() {
        salida.println("conocerNombrePartida");
    }

    private void avisarClienteNombrePartida(String nombrePartida, String tiemTur, String tipMis) {
        vec.setNombrePartida(nombrePartida);
        vec.setTiempoTurno(Integer.parseInt(tiemTur));
        vec.setTipoMision(Integer.parseInt(tipMis));
    }

    public void avisarInicioPartida() {
        salida.println("avisarInicioPartida");
    }

    public void setVentanaPrincipal(VPrincipal vp) {
        this.vp = vp;
    }

    public void mandarMensaje(String mensaje) {
        salida.println("mensaje" + delimitador + mensaje);
    }

    private ArrayList<Jugador> construirArrayJugadores(ArrayList<String> contenidoLineaEntrada) {
        ArrayList<Jugador> jugadores = new ArrayList();
        int cantidadJugadores = Integer.parseInt(contenidoLineaEntrada.get(1));
        int contId = 2;
        int contNombre = 3;
        int contColor = 4;

        for (int i = 0; i < cantidadJugadores; i++) {
            int id = Integer.parseInt(contenidoLineaEntrada.get(contId));
            String nombre = contenidoLineaEntrada.get(contNombre);
            String color = contenidoLineaEntrada.get(contColor);

            jugadores.add(new Jugador(id, nombre, color));
            //5 id
            //6 nombre
            //7 color
            contId += 3;
            contNombre += 3;
            contColor += 3;
        }
        return jugadores;
    }

    private int[] construirArrayPaises(ArrayList<String> contenidoLineaEntrada) {
        int[] arrayPaises = new int[50];
        int comenzar = 2 + Integer.parseInt(contenidoLineaEntrada.get(1)) * 3;
        for (int i = comenzar; i < contenidoLineaEntrada.size() - 2; i = i + 3) {
            arrayPaises[Integer.parseInt(contenidoLineaEntrada.get(i))] = Integer.parseInt(contenidoLineaEntrada.get(i + 1));
            tarjetas[Integer.parseInt(contenidoLineaEntrada.get(i))] = Integer.parseInt(contenidoLineaEntrada.get(i + 2));
        }
        return arrayPaises;
    }

    public int getIdJugador() {
        return id;
    }

    public void avisarAgregacionDeTropa(int idB) {
        salida.println("nuevaTropaPais" + delimitador + idB);
    }

    public void avisarFinTurno() {
        salida.println("finTurno");
    }

    public void avisarAtaque(String avisar) {
        salida.println(avisar);
    }

    public void avisarReagrupacion(String avisar) {
        salida.println(avisar);
    }

    public void avisarFinPartida() {
        salida.println("finPartida");
    }

    public void avisarSolicitudTarjeta() {
        salida.println("solicitudTarjeta");
    }

    public void avisarUsoTarjeta(int idPais) {
        salida.println("usoTarjeta" + delimitador + idPais);
    }

    public void avisarCanjeTarjeta(int idP1, int idP2, int idP3) {

        salida.println("canjeTarjeta" + delimitador + idP1 + delimitador + idP2 + delimitador + idP3);
    }

    public void avisarFinDeMazoTarjeta() {
        salida.println("finMazoTarjeta");
    }
}
